<?php

namespace App\Services;

use Overtrue\LaravelWeChat\Facade as EasyWechat;
use App\Models\Material;

class WechatMaterialService
{
    protected $needUpdatedMediaIds = [];

    /**
     * 同步图文素材
     * @param $list
     */
    public function syncNews($list)
    {
        $mediaIds = array_column($list, 'media_id');
        // 查询在媒体库里的素材
        $dbNewsMediaIds = $this->getDbMaterialMediaIds(Material::TYPE_NEWS);

        // 删除数据库中已被删除的素材
        $this->deleteUselessMaterial($dbNewsMediaIds, $mediaIds);

        // 更新或创建素材
        $this->needUpdatedMediaIds = array_intersect($dbNewsMediaIds, $mediaIds);
        foreach ($list as $item) {
            $this->updateOrCreateNews($item['content']['news_item'], $item['media_id'], $item['update_time']);
        }
    }

    /**
     * 同步图片素材
     * @param $list
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     */
    public function syncImages($list)
    {
        $mediaIds = array_column($list, 'media_id');
        // 获取数据库中的所有的图片素材id
        $dbImageIds = $this->getDbMaterialMediaIds(Material::TYPE_IMAGE);

        // 需要已被删除的图片id
        $this->deleteUselessMaterial($dbImageIds, $mediaIds);

        // 更新或创建素材
        $this->needUpdatedMediaIds = array_intersect($dbImageIds, $mediaIds);
        foreach ($list as $image) {
            // 删除无用的cropImage，微信遗留的bug
            if ($image['name'] == 'CropImage') {
                $this->deleteCropImage($image['media_id']);
                continue;
            }

            $image['type'] = Material::TYPE_IMAGE;
            if (!in_array($image['media_id'], $this->needUpdatedMediaIds)) {
                Material::query()->create($image);
            } else {
                Material::query()->where('media_id', $image['media_id'])->update($image);
            }
        }

    }

    /**
     * 更新或创建图文素材
     * @param $newsItems
     * @param $mediaId
     * @param $updateTime
     */
    protected function updateOrCreateNews($newsItems, $mediaId, $updateTime)
    {
        foreach ($newsItems as $index => $news) {
            $news['type'] = Material::TYPE_NEWS;
            $news['media_id'] = $mediaId;
            $news['index'] = $index;
            $news['update_time'] = $updateTime;

            if (!in_array($mediaId, $this->needUpdatedMediaIds)) {
                // 新增素材
                Material::query()->create($news);
            } else {
                // 更新素材
                Material::query()->where('media_id', $mediaId)
                    ->where('index', $index)
                    ->update($news);
            }
        }
    }


    /**
     * 获取数据库中记录的media_id
     * @param string $type 素材类型
     * @return array
     */
    protected function getDbMaterialMediaIds($type)
    {
        if (!in_array($type, array_keys(Material::$typesMap))) {
            return [];
        }

        return Material::query()
            ->where('type', $type)
            ->get(['media_id'])
            ->pluck('media_id')
            ->all();
    }

    /**
     * 删除线上已删除的素材
     * @param array $dbMediaIds 数据库中的 media_id
     * @param array $mediaIds  服务器返回的 media_id
     */
    protected function deleteUselessMaterial($dbMediaIds, $mediaIds)
    {
        $needDeletedMediaIds = array_diff($dbMediaIds, $mediaIds);
        if ($needDeletedMediaIds) {
            Material::query()->whereIn('media_id', $needDeletedMediaIds)->delete();
        }
    }

    /**
     * @param $mediaId
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     */
    protected function deleteCropImage($mediaId)
    {
        $app = EasyWechat::officialAccount();
        $app->material->delete($mediaId);
    }


}